package com.fms.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fms.sys.dto.PasswordCategoryDTO;
import com.fms.sys.dto.PasswordInfoDTO;
import com.fms.sys.entity.PasswordCategory;
import com.fms.sys.entity.PasswordInfo;
import com.fms.sys.mapper.PasswordCategoryMapper;
import com.fms.sys.mapper.PasswordInfoMapper;
import com.fms.sys.service.PasswordService;
import com.fms.sys.service.IUserService;
import com.fms.common.exception.BusinessException;
import com.fms.common.utils.JwtUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class PasswordServiceImpl implements PasswordService {
    @Autowired
    private PasswordCategoryMapper categoryMapper;

    @Autowired
    private PasswordInfoMapper passwordMapper;

    @Autowired
    private IUserService userService;

    /**
     * 获取当前登录用户ID
     * 
     * @return 当前用户ID
     * @throws BusinessException 如果未登录或token无效
     */
    private Long getCurrentUserId() {
        Long userId = JwtUtils.getCurrentUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录或登录已过期");
        }
        return userId;
    }

    /**
     * 验证数据所属权
     * 
     * @param ownerId 数据所属用户ID
     * @throws BusinessException 如果不属于当前用户
     */
    private void validateOwnership(Long ownerId) {
        if (!getCurrentUserId().equals(ownerId)) {
            throw new BusinessException("无权访问该数据");
        }
    }

    @Override
    public List<PasswordCategoryDTO> listCategories() {
        LambdaQueryWrapper<PasswordCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PasswordCategory::getUserId, getCurrentUserId());
        List<PasswordCategory> categories = categoryMapper.selectList(wrapper);
        return categories.stream().map(category -> {
            PasswordCategoryDTO dto = new PasswordCategoryDTO();
            BeanUtils.copyProperties(category, dto);
            // 统计每个分类下的密码数量
            LambdaQueryWrapper<PasswordInfo> pwdWrapper = new LambdaQueryWrapper<>();
            pwdWrapper.eq(PasswordInfo::getCategoryId, category.getId())
                    .eq(PasswordInfo::getUserId, getCurrentUserId());
            dto.setPasswordCount(passwordMapper.selectCount(pwdWrapper));
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public PasswordCategoryDTO addCategory(PasswordCategory category) {
        category.setUserId(getCurrentUserId());
        categoryMapper.insert(category);
        PasswordCategoryDTO dto = new PasswordCategoryDTO();
        BeanUtils.copyProperties(category, dto);
        dto.setPasswordCount(0L);
        return dto;
    }

    @Override
    public void updateCategory(PasswordCategory category) {
        // 验证分类所属权
        PasswordCategory original = categoryMapper.selectById(category.getId());
        if (original != null) {
            validateOwnership(original.getUserId());
            category.setUserId(getCurrentUserId());
            categoryMapper.updateById(category);
        }
    }

    @Override
    public void deleteCategory(Long id) {
        // 验证分类所属权
        PasswordCategory category = categoryMapper.selectById(id);
        if (category != null) {
            validateOwnership(category.getUserId());
            categoryMapper.deleteById(id);
        }
    }

    @Override
    public IPage<PasswordInfoDTO> listPasswords(Page<PasswordInfo> page, String keyword, Long categoryId) {
        LambdaQueryWrapper<PasswordInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PasswordInfo::getUserId, getCurrentUserId());

        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(PasswordInfo::getTitle, keyword)
                    .or()
                    .like(PasswordInfo::getUsername, keyword)
                    .or()
                    .like(PasswordInfo::getWebsite, keyword));
        }
        if (categoryId != null) {
            wrapper.eq(PasswordInfo::getCategoryId, categoryId);
        }
        wrapper.orderByDesc(PasswordInfo::getCreateTime);

        IPage<PasswordInfo> passwordPage = passwordMapper.selectPage(page, wrapper);
        return passwordPage.convert(password -> {
            PasswordInfoDTO dto = new PasswordInfoDTO();
            BeanUtils.copyProperties(password, dto);
            // 获取分类名称
            PasswordCategory category = categoryMapper.selectById(password.getCategoryId());
            if (category != null) {
                dto.setCategoryName(category.getName());
            }
            return dto;
        });
    }

    @Override
    public PasswordInfoDTO addPassword(PasswordInfo password) {
        password.setUserId(getCurrentUserId());
        // 加密密码
        password.setPassword(encryptPassword(password.getPassword()));
        passwordMapper.insert(password);
        PasswordInfoDTO dto = new PasswordInfoDTO();
        BeanUtils.copyProperties(password, dto);
        // 获取分类名称
        PasswordCategory category = categoryMapper.selectById(password.getCategoryId());
        if (category != null) {
            dto.setCategoryName(category.getName());
        }
        return dto;
    }

    @Override
    public void updatePassword(PasswordInfo password) {
        // 验证密码所属权
        PasswordInfo original = passwordMapper.selectById(password.getId());
        if (original != null && original.getUserId().equals(getCurrentUserId())) {
            password.setUserId(getCurrentUserId());
            // 如果密码被修改，需要重新加密
            if (!original.getPassword().equals(password.getPassword())) {
                password.setPassword(encryptPassword(password.getPassword()));
            }
            passwordMapper.updateById(password);
        }
    }

    @Override
    public void deletePassword(Long id) {
        // 验证密码所属权
        PasswordInfo password = passwordMapper.selectById(id);
        if (password != null && password.getUserId().equals(getCurrentUserId())) {
            passwordMapper.deleteById(id);
        }
    }

    @Override
    public String encryptPassword(String password) {
        // TODO: 使用加密算法加密密码
        return password;
    }

    @Override
    public String decryptPassword(String encryptedPassword) {
        // TODO: 使用解密算法解密密码
        return encryptedPassword;
    }
}